/**
 * @author: 徐南木
 * @date: 2022/2/20 5:34
 * @description: 
 */

#include "datetime.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

const char* getDateTime(const char *format,int flag){
    switch (flag){
        case SECOND: return getDateTimeSecond_t(format);
        case MILLISECOND: return getDateTimeMillisecond_t(format);
        case MICROSECONDS: return getDateTimeMicrosecond_t(format);
        case NANOSECOND: return getDateTimeNanosecond_t(format);
        default: return "";
    }
}


const char* getDateTimeSecond_t(const char *format){
    char* now_time = malloc(128);
    time_t time_t = time(NULL);
    struct tm tm;
    localtime_r(&time_t,&tm);
    strftime(now_time, 128, format, &tm);
    return now_time;
}

const char* getDateTimeMillisecond_t(const char *format){
    char* now_time = malloc(128);
    struct timespec timespec;
    clock_gettime(CLOCK_REALTIME,&timespec);
    struct tm tm;
    localtime_r(&timespec.tv_sec,&tm);
    size_t i = strftime(now_time, 128, format, &tm);
    size_t j = 4;
    char buf[5]={'.','0','0','0',0};
    timespec.tv_nsec /= 1000000;
    while (timespec.tv_nsec){
        buf[--j] = timespec.tv_nsec%10 + '0';
        timespec.tv_nsec /= 10;
    }
    for (j = 0; j < 5; ++j) {
        now_time[i+j] = buf[j];
    }
    return now_time;
}

const char* getDateTimeMicrosecond_t(const char *format){
    char* now_time = malloc(128);
    struct timespec timespec;
    clock_gettime(CLOCK_REALTIME,&timespec);
    struct tm tm;
    localtime_r(&timespec.tv_sec,&tm);
    size_t i = strftime(now_time, 128, format, &tm);
    size_t j = 7;
    char buf[8]={'.','0','0','0','0','0','0',0};
    timespec.tv_nsec /= 1000;
    while (timespec.tv_nsec){
        buf[--j] = timespec.tv_nsec%10 + '0';
        timespec.tv_nsec /= 10;
    }
    for (j = 0; j < 8; ++j) {
        now_time[i+j] = buf[j];
    }
    return now_time;
}

const char* getDateTimeNanosecond_t(const char *format){
    char* now_time = malloc(128);
    struct timespec timespec;
    clock_gettime(CLOCK_REALTIME,&timespec);
    struct tm tm;
    localtime_r(&timespec.tv_sec,&tm);
    size_t i = strftime(now_time, 128, format, &tm);
    size_t j = 10;
    char buf[11]={'.','0','0','0','0','0','0','0','0','0',0};
    while (timespec.tv_nsec){
        buf[--j] = timespec.tv_nsec%10 + '0';
        timespec.tv_nsec /= 10;
    }
    for (j = 0; j < 11; ++j) {
        now_time[i+j] = buf[j];
    }
    return now_time;
}

static char now_time[128];

const char* getDateTimeSecond(const char *format){
    time_t time_t = time(NULL);
    struct tm tm;
    localtime_r(&time_t,&tm);
    strftime(now_time, 128, format, &tm);
    return now_time;
}

const char*getDateTimeMillisecond(const char *format){
    struct timespec timespec;
    clock_gettime(CLOCK_REALTIME,&timespec);
    struct tm tm;
    localtime_r(&timespec.tv_sec,&tm);
    size_t i = strftime(now_time, 128, format, &tm);
    size_t j = 4;
    char buf[5]={'.','0','0','0',0};
    timespec.tv_nsec /= 1000000;
    while (timespec.tv_nsec){
        buf[--j] = timespec.tv_nsec%10 + '0';
        timespec.tv_nsec /= 10;
    }
    for (j = 0; j < 5; ++j) {
        now_time[i+j] = buf[j];
    }
    return now_time;
}

const char* getDateTimeMicrosecond(const char *format){
    struct timespec timespec;
    clock_gettime(CLOCK_REALTIME,&timespec);
    struct tm tm;
    localtime_r(&timespec.tv_sec,&tm);
    size_t i = strftime(now_time, 128, format, &tm);

    size_t j = 7;
    char buf[8]={'.','0','0','0','0','0','0',0};
    timespec.tv_nsec /= 1000;
    while (timespec.tv_nsec){
        buf[--j] = timespec.tv_nsec%10 + '0';
        timespec.tv_nsec /= 10;
    }
    for (j = 0; j < 8; ++j) {
        now_time[i+j] = buf[j];
    }
    return now_time;
}

const char* getDateTimeNanosecond(const char *format){
    struct timespec timespec;
    clock_gettime(CLOCK_REALTIME,&timespec);
    struct tm tm;
    localtime_r(&timespec.tv_sec,&tm);
    size_t i = strftime(now_time, 128, format, &tm);
    size_t j = 10;
    char buf[11]={'.','0','0','0','0','0','0','0','0','0',0};
    while (timespec.tv_nsec){
        buf[--j] = timespec.tv_nsec%10 + '0';
        timespec.tv_nsec /= 10;
    }
    for (j = 0; j < 11; ++j) {
        now_time[i+j] = buf[j];
    }
    return now_time;
}